package com.zh.work.util.jy;


import sun.misc.BASE64Decoder;


import javax.imageio.ImageIO;
import java.awt.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

public class Base64ImgUtil {
    public static void main(String[] args) {
        // 测试从图片文件转换为Base64编码
        String strImg = "";
        //GetImageStr("e://Koala.jpg");
        // 测试从Base64编码转换为图片文件
        GenerateImage(strImg, "d:\\123456.jpg");

    }

    /**
     * 根据图片路径对图片进行BASE64编码
     *
     * @param imgFilePath 图片文件所在路径
     * @return 图片的base64编码字符串
     */
    public static String GetImageStr(String imgFilePath) {
        if (imgFilePath == null || ("").equals(imgFilePath)) {
            return null;
        }
        byte[] data = null;
        InputStream in = null;
        // 读取图片字节数组
        try {
            if (imgFilePath.contains("http")) {
               return  getURLImage(imgFilePath);
            } else {
                in = new FileInputStream(imgFilePath);
            }
            int count = -1;//in.available有可能为0所以不能用0做默认值,否则会死循环
            while (count == -1) {
                count = in.available();
            }
            if (count <= 0) {
                return null;
            }
            data = new byte[count];
            in.read(data);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();

            }
        }
        // 对字节数组Base64编码
        return BASE64Encoder.encode(data);
    }

    /**
     * 对BASE64字符串解码并保存成文件
     *
     * @param imgStr      base64编码的字符串
     * @param imgFilePath 保存图片的文件路径
     * @return 成功或失败
     */
    public static boolean GenerateImage(String imgStr, String imgFilePath) {
        if (imgStr == null || ("").equals(imgStr)
                || imgFilePath == null || ("").equals(imgFilePath))
            return false;
        BASE64Decoder decoder = new BASE64Decoder();
        OutputStream out = null;
        BufferedOutputStream bos = null;
        try {
            // Base64解码
            byte[] bytes = decoder.decodeBuffer(imgStr);
            // 生成jpeg图片
            out = new FileOutputStream(imgFilePath);
//			out.write(bytes);
//			out.flush();
            bos = new BufferedOutputStream(out);
            // 使用缓冲区写二进制字节数据
            bos.write(bytes);
            // BufferedReader //读取
            // BufferedWriter //写入
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (bos != null)
                    bos.close();
                if (out != null)
                    out.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();

            }
        }
    }

    /**
     * 对BASE64字符串解码并保存成字节数组
     *
     * @param imgStr base64编码的字符串
     * @return 返回Base64解码后的字节数组
     */
    public static byte[] GenerateImageByte(String imgStr) {
        if (imgStr == null || ("").equals(imgStr))
            return null;
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // Base64解码
            byte[] bytes = decoder.decodeBuffer(imgStr);
            for (int i = 0, j = bytes.length; i < j; ++i) {
                if (bytes[i] < 0) {// 调整异常数据
                    bytes[i] += 256;
                }
            }
            return bytes;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @param p_Str Base64编码的字符窜
     * @return byte[]类型的照片信息
     * @throws IOException
     */
    public static byte[] fromBase64(String p_Str) throws IOException {
        if (p_Str == null)
            return null;
        byte[] byteBuffer = new BASE64Decoder().decodeBuffer(p_Str);
        return byteBuffer;
    }

    /**
     * @param bytes byte[]类型的照片信息
     * @return Java Image对象。可以直接在java程序中绘制到UI界面
     */
    public static Image getImage(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        Image img = null;
        InputStream isPhoto = null;
        try {
            isPhoto = new ByteArrayInputStream(bytes);
            img = ImageIO.read(isPhoto);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                if (isPhoto != null) {
                    isPhoto.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();

            }
        }
        return img;
    }

    public static InputStream getImageStream(String url) {
        try {
            HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
            connection.setReadTimeout(5000);
            connection.setConnectTimeout(5000);
            connection.setRequestMethod("GET");
            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = connection.getInputStream();
                return inputStream;
            }
        } catch (IOException e) {
            System.out.println("获取网络图片出现异常，图片路径为：" + url);
            e.printStackTrace();
        }
        return null;
    }


    public static String getURLImage(String imageUrl) {
        String base64String = "";
        try {
            //new一个URL对象
            URL url = new URL(imageUrl);
            //打开链接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //设置请求方式为"GET"
            conn.setRequestMethod("GET");
            //超时响应时间为5秒
            conn.setConnectTimeout(5 * 1000);
            //通过输入流获取图片数据
            InputStream inStream = conn.getInputStream();
            //得到图片的二进制数据，以二进制封装得到数据，具有通用性
            byte[] data = readInputStream(inStream);
            BASE64Encoder encode = new BASE64Encoder();
            //转base64的字符串
            base64String = BASE64Encoder.encode(data);

            //下一步可以直接使用图片调接口或者写本地
            Base64ImgUtil.GenerateImage(base64String,"D:\\card.jpg");

        } catch (Exception e) {
            e.printStackTrace();
        }
        return base64String;
    }

    private static byte[] readInputStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        //创建一个Buffer字符串
        byte[] buffer = new byte[1024];
        //每次读取的字符串长度，如果为-1，代表全部读取完毕
        int len = 0;
        //使用一个输入流从buffer里把数据读取出来
        while ((len = inStream.read(buffer)) != -1) {
            //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
            outStream.write(buffer, 0, len);
        }
        //关闭输入流
        inStream.close();
        //把outStream里的数据写入内存
        return outStream.toByteArray();
    }
}
